Option Strict On
Option Explicit On

'Copyright (c) 2007-2010, William Severance, Jr., WESNet Designs
'All rights reserved.

'Redistribution and use in source and binary forms, with or without modification, are permitted
'provided that the following conditions are met:

'Redistributions of source code must retain the above copyright notice, this list of conditions
'and the following disclaimer.

'Redistributions in binary form must reproduce the above copyright notice, this list of conditions
'and the following disclaimer in the documentation and/or other materials provided with the distribution.

'Neither the name of William Severance, Jr. or WESNet Designs may be used to endorse or promote
'products derived from this software without specific prior written permission.

'Disclaimer: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
'            OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
'            AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE
'            FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
'            LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
'            INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
'            OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
'            IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

'Although I will try to answer questions regarding the installation and use of this software when
'such questions are submitted via e-mail to the below address, no promise of further
'support or enhancement is made nor should be assumed.

'Developer Contact Information:
'     William Severance, Jr.
'     WESNet Designs
'     679 Upper Ridge Road
'     Bridgton, ME 04009
'     Phone: 207-647-9375
'     E-Mail: bill@wesnetdesigns.com
'     Website: www.wesnetdesigns.com

Imports DotNetNuke
Imports DotNetNuke.Entities.Modules
Imports DotNetNuke.Security
Imports DotNetNuke.Services.Exceptions



Namespace WESNet.DNN.Modules.EPrayer

    Partial Class ManageUsers
        Inherits EPrayerModuleBase

#Region "Private Members"
        Private _FilterOn As String = "U.Username"
        Private _Letter As Char = Chr(0)
        Private _Trusted As Integer = -1
        Private _Banned As Integer = -1
        Private _OrderByField As String = "U.Username"
        Private _OrderByDirection As String = "ASC"
        Private _UserID As Integer = -1

        Private ValidOrderByFields As String() = New String() {"U.Username", "U.Displayname", "EU.Alias"}

#End Region

#Region "Public Properties"

        Public Overrides Property PageSize() As Integer
            Get
                If trPager.Visible Then
                    Return Convert.ToInt32(ddlPageSize.SelectedValue)
                Else
                    Return MyBase.PageSize
                End If
            End Get
            Set(ByVal value As Integer)
                If trPager.Visible Then
                    Dim li As ListItem
                    li = ddlPageSize.Items.FindByValue(value.ToString)
                    If Not li Is Nothing Then
                        ddlPageSize.SelectedIndex = ddlPageSize.Items.IndexOf(li)
                        MyBase.PageSize = value
                    End If
                Else
                    MyBase.PageSize = value
                End If
            End Set
        End Property

        Public Property FilterOn() As String
            Get
                If ddlFilterOn.SelectedIndex <> -1 Then
                    Return ddlFilterOn.SelectedValue
                Else
                    Return _FilterOn
                End If
            End Get
            Set(ByVal value As String)
                Dim li As ListItem = ddlFilterOn.Items.FindByValue(value)
                If Not li Is Nothing Then
                    ddlFilterOn.SelectedIndex = ddlFilterOn.Items.IndexOf(li)
                    _FilterOn = value
                End If
            End Set
        End Property

        Public Property Letter() As Char
            Get
                Return _Letter
            End Get
            Set(ByVal value As Char)
                _Letter = value
            End Set
        End Property

        Public Property Trusted() As Integer
            Get
                Return _Trusted
            End Get
            Set(ByVal value As Integer)
                _Trusted = value
            End Set
        End Property

        Public Property Banned() As Integer
            Get
                Return _Banned
            End Get
            Set(ByVal value As Integer)
                _Banned = value
            End Set
        End Property

        Public Property OrderByField() As String
            Get
                Return _OrderByField
            End Get
            Set(ByVal value As String)
                _OrderByField = value
            End Set
        End Property

        Public Property OrderByDirection() As String
            Get
                Return _OrderByDirection
            End Get
            Set(ByVal value As String)
                _OrderByDirection = value
            End Set
        End Property

#End Region

#Region "Private Properties"
        Private ReadOnly Property Filter() As String
            Get
                Dim sb As New StringBuilder

                If Letter <> Chr(0) Then
                    If sb.Length > 0 Then sb.Append(" AND ")
                    sb.Append("(")
                    sb.Append(FilterOn)
                    sb.Append(" LIKE '")
                    sb.Append(Letter)
                    sb.Append("%')")
                End If

                If Trusted <> -1 Then
                    If sb.Length > 0 Then sb.Append(" AND ")
                    sb.Append("(EU.IsTrusted=")
                    sb.Append(Trusted.ToString)
                    sb.Append(")")
                End If

                If Banned <> -1 Then
                    If sb.Length > 0 Then sb.Append(" AND ")
                    sb.Append("(EU.IsBanned=")
                    sb.Append(Banned.ToString)
                    sb.Append(")")
                End If

                Return sb.ToString
            End Get
        End Property

        Public Property OrderBy() As String
            Get
                Return OrderByField & "_" & OrderByDirection
            End Get
            Set(ByVal value As String)
                If value.Length = 0 Then
                    OrderByField = "U.Username"
                    OrderByDirection = "ASC"
                Else
                    Dim s() As String = value.Split("_"c)
                    If Array.IndexOf(ValidOrderByFields, s(0)) = -1 Then
                        Throw New ArgumentException("Invalid fieldname")
                    Else
                        OrderByField = s(0)
                    End If
                    Select Case s.Length
                        Case 1
                            OrderByDirection = "ASC"
                        Case 2
                            OrderByDirection = s(1)
                        Case Else
                            Throw New ArgumentException("Invalid direction")
                    End Select
                End If
            End Set
        End Property
#End Region

#Region "Private Methods"
        Private Sub PopulateFilterRepeater()
            Dim Links As New ArrayList
            Dim Letters As String = Localization.GetString("Letters.Text", LocalResourceFile)
            If Letters Is Nothing Then
                For i As Int32 = Asc("A") To Asc("Z")
                    Links.Add(New String(Chr(i), 1))
                Next
            Else
                Links.AddRange(Letters.Split(" "c))
            End If

            Links.Add(Localization.GetString("All"))
            Links.Add(Localization.GetString("Trusted", LocalResourceFile))
            Links.Add(Localization.GetString("Untrusted", LocalResourceFile))
            Links.Add(Localization.GetString("Banned", LocalResourceFile))
            rptFilterUsers.DataSource = Links
            rptFilterUsers.DataBind()
        End Sub

        Private Sub PopulateDistributionList()
            Dim epc As New EPrayerController()
            With cblViewableDistributions
                .DataSource = epc.GetDistributions(ModuleId)
                .DataBind()
            End With
        End Sub

        Private Sub BindData()
            Dim TotalRecords As Integer
            Dim epc As New EPrayerController

            Dim objUsers As Generic.List(Of UserInfo) = epc.GetUsers(ModuleId, Filter, OrderBy.Replace("_", " "), PageSize, CurrentPage - 1, TotalRecords)
            gvUsers.DataSource = objUsers
            gvUsers.DataBind()

            If TotalRecords > 0 Then
                With ctlPager
                    .TotalRecords = TotalRecords
                    .QuerystringParams = "&ctl=mngusers&mid=" & ModuleId.ToString & GetQueryString(GetQueryStringParams())
                    .Visible = PageSize <> 0 And TotalRecords > PageSize
                End With
                trPager.Visible = True
                trError.Visible = False
            Else
                trPager.Visible = False
                trError.Visible = True
                lblError.Text = Localize("No_Users_Found")
            End If

        End Sub

        Public Overloads Function GetQueryStringParams() As String()
            Return GetQueryStringParams(CurrentPage, FilterOn, Letter, Trusted, Banned, OrderBy)
        End Function

        Public Overloads Function GetQueryStringParams(ByVal CommandName As String) As String()
            If CommandName.Length = 1 Then
                Return GetQueryStringParams(1, FilterOn, Convert.ToChar(CommandName), -1, -1, OrderBy)
            End If

            Select Case CommandName
                Case Localization.GetString("All")
                    Return GetQueryStringParams(1, FilterOn, Chr(0), -1, -1, OrderBy)
                Case Localization.GetString("Trusted", LocalResourceFile)
                    Return GetQueryStringParams(1, FilterOn, Letter, 1, -1, OrderBy)
                Case Localization.GetString("Untrusted", LocalResourceFile)
                    Return GetQueryStringParams(1, FilterOn, Letter, 0, -1, OrderBy)
                Case Localization.GetString("Banned", LocalResourceFile)
                    Return GetQueryStringParams(1, FilterOn, Letter, -1, 1, OrderBy)
                Case Else
                    Return GetQueryStringParams()
            End Select
        End Function

        Public Overloads Function GetQueryStringParams(ByVal Banned As Integer) As String()
            Return GetQueryStringParams(1, "", Chr(0), -1, Banned, OrderBy)
        End Function

        Public Overloads Function GetQueryStringParams(ByVal CurrentPage As Integer, ByVal FilterOn As String, _
                                                          ByVal Letter As Char, ByVal Trusted As Integer, _
                                                          ByVal Banned As Integer, ByVal OrderBy As String) As String()
            Dim params As New ArrayList
            If PageSize <> MyConfiguration.PageSize Then params.Add("pagesize=" & PageSize.ToString)
            If CurrentPage <> 1 Then params.Add("currentpage=" & CurrentPage.ToString)
            If FilterOn <> "U.Username" Then params.Add("filteron=" & FilterOn)
            If Letter <> Chr(0) Then params.Add("letter=" & Letter.ToString)
            If Trusted <> -1 Then params.Add("trusted=" & Trusted.ToString)
            If Banned <> -1 Then params.Add("banned=" & Banned.ToString)
            If OrderBy <> "U.Username_ASC" Then params.Add("orderby=" & OrderBy.ToString)
            If _UserID <> -1 Then params.Add("userid=" & _UserID.ToString)
            Return CType(params.ToArray(GetType(String)), String())
        End Function

        Public Function GetQueryString(ByVal params As String()) As String
            Dim sb As New StringBuilder
            For Each s As String In params
                If Not s.StartsWith("currentpage") Then
                    sb.Append("&")
                    sb.Append(s)
                End If
            Next
            Return sb.ToString
        End Function

        Public Overloads Function EditUrl(ByVal params() As String) As String
            Return MyBase.EditUrl("", "", "mngusers", params)
        End Function

        Private Sub Submit()
            Try
                Dim _Signature As String
                Dim UserID As Integer

                ' Check Signature field for cross site scripting
                Dim ps As New PortalSecurity
                _Signature = ps.InputFilter(teSignature.Text, PortalSecurity.FilterFlag.NoScripting)

                If _UserID = -1 Then
                    UserID = CType(gvUsers.DataKeys(gvUsers.EditIndex).Value, Integer)
                Else
                    UserID = _UserID
                End If

                Dim epc As New EPrayerController
                Dim objUser As UserInfo = epc.GetUser(ModuleId, UserID)
                With objUser
                    .Alias = tbAlias.Text
                    .Signature = Server.HtmlDecode(_Signature)
                    .IsTrusted = cbIsTrusted.Checked
                    .IsBanned = cbIsBanned.Checked
                    If Not String.IsNullOrEmpty(tbBannedUntilDate.Text) Then
                        .BannedUntilDate = DateTime.Parse(tbBannedUntilDate.Text)
                    Else
                        .BannedUntilDate = Null.NullDate
                    End If
                    .ViewableDistributions = Utilities.DistributionCBLGet(cblViewableDistributions, False)
                End With
                epc.UpdateUser(objUser)
                epc.ClearUserCache(ModuleId, UserID)
                If _UserID = -1 Then
                    trDetailsView.Visible = False
                    cmdReturn.Visible = True
                    gvUsers.EditIndex = -1
                    BindData()
                Else
                    Response.Redirect(ReturnUrl, True)
                End If
            Catch exc As Exception
                ProcessModuleLoadException(Me, exc)
            End Try
        End Sub

        Private Sub DisplayUser(ByVal UserID As Integer, ByVal HideGrid As Boolean)
            Dim epc As New EPrayerController
            Dim objUser As UserInfo = epc.GetUser(ModuleId, UserID)
            If objUser Is Nothing Then
                trError.Visible = True
                lblError.Text = String.Format(Localize("User_Not_Found.Error"), UserID)
            Else
                trDetailsView.Visible = True
                If HideGrid Then
                    tblFilterUsers.Visible = False
                    trUsers.Visible = False
                    trPager.Visible = False
                    cmdReturn.Visible = True
                    cmdCancel.Visible = False
                Else
                    cmdReturn.Visible = False
                    cmdCancel.Visible = True
                End If

                With objUser
                    lblUsername.Text = .Username
                    lblDisplayname.Text = .DisplayName
                    tbAlias.Text = .Alias
                    If String.IsNullOrEmpty(.Signature) Then
                        teSignature.RichText.Text = ""
                    Else
                        teSignature.Text = .Signature
                    End If
                    cbIsTrusted.Checked = .IsTrusted
                    cbIsModerator.Checked = .IsModerator
                    cbIsBanned.Checked = .IsBanned
                    If cbIsBanned.Checked Then
                        tbBannedUntilDate.Style.Add("display", "")
                        cmdBannedUntilDateCalendar.Style.Add("display", "")
                        If Null.IsNull(.BannedUntilDate) Then
                            tbBannedUntilDate.Text = String.Empty
                        Else
                            tbBannedUntilDate.Text = .BannedUntilDate.ToShortDateString()
                        End If
                    Else
                        tbBannedUntilDate.Style.Add("display", "none")
                        cmdBannedUntilDateCalendar.Style.Add("display", "none")
                        tbBannedUntilDate.Text = String.Empty
                    End If
                    Utilities.DistributionCBLSet(cblViewableDistributions, .ViewableDistributions)
                End With
            End If
        End Sub

#End Region

#Region "Event Handlers"

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            Try
                If Not (IsAdministrator OrElse (MyConfiguration.EnableModeration And CanModerate)) Then Response.Redirect(AccessDeniedURL(), True)

                If Not String.IsNullOrEmpty(Request.QueryString("userid")) Then
                    _UserID = Convert.ToInt32(Request.QueryString("userid"))
                End If

                If Not String.IsNullOrEmpty(Request.QueryString("currentpage")) Then
                    CurrentPage = Convert.ToInt32(Request.QueryString("currentpage"))
                Else
                    CurrentPage = 1
                End If

                Dim RequestedPageSize As Integer
                If Not String.IsNullOrEmpty(Request.QueryString("pagesize")) Then
                    RequestedPageSize = Convert.ToInt32(Request.QueryString("pagesize"))
                Else
                    RequestedPageSize = UserInfo.PageSize
                End If

                If Not Page.IsPostBack Then
                    PopulatePageSizes(ddlPageSize, RequestedPageSize)
                    PageSize = RequestedPageSize
                    PopulateFilterRepeater()
                    PopulateDistributionList()
                Else
                    If PageSize = -1 Then PageSize = RequestedPageSize
                End If

                ctlPager.PageSize = RequestedPageSize
                ctlPager.CurrentPage = CurrentPage
                ctlPager.TabID = TabId


                If Not String.IsNullOrEmpty(Request.QueryString("letter")) Then Letter = Convert.ToChar(Request.QueryString("letter"))
                If Not String.IsNullOrEmpty(Request.QueryString("trusted")) Then Trusted = Convert.ToInt32(Request.QueryString("trusted"))
                If Not String.IsNullOrEmpty(Request.QueryString("banned")) Then Banned = Convert.ToInt32(Request.QueryString("banned"))
                If Not String.IsNullOrEmpty(Request.QueryString("orderby")) Then OrderBy = Request.QueryString("orderby")
                cmdBannedUntilDateCalendar.NavigateUrl = DotNetNuke.Common.Utilities.Calendar.InvokePopupCal(tbBannedUntilDate)

                If Not Page.IsPostBack Then
                    If _UserID = -1 Then
                        If Not String.IsNullOrEmpty(Request.QueryString("filteron")) Then FilterOn = Request.QueryString("filteron")
                        PopulateFilterRepeater()
                        Utilities.LocalizeGridView(gvUsers, LocalResourceFile)
                        gvUsers.Columns(6).Visible = MyConfiguration.TrackVisits
                        gvUsers.Columns(7).Visible = MyConfiguration.TrackNewPosts

                        'Do not show Profile selection command unless user is administrator
                        CType(gvUsers.Columns(8), System.Web.UI.WebControls.CommandField).ShowSelectButton = IsAdministrator
                        BindData()
                    Else
                        DisplayUser(_UserID, True)
                    End If
                End If
            Catch exc As Exception
                ProcessModuleLoadException(Me, exc)
            End Try

        End Sub

        Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
            cbIsBanned.Attributes.Add("onClick", "javascript: setBannedDateVisibility('" & cbIsBanned.ClientID & "', '" & tbBannedUntilDate.ClientID & "', '" & cmdBannedUntilDateCalendar.ClientID & "');")
            Dim SettingsScript As New StringBuilder
            With SettingsScript
                .AppendLine("function setBannedDateVisibility (cb1, tb1, lnk1) {")
                .AppendLine("    if (document.getElementById) {")
                .AppendLine("         var cb1=document.getElementById(cb1);")
                .AppendLine("         var tb1=document.getElementById(tb1);")
                .AppendLine("         var lnk1=document.getElementById(lnk1);")
                .AppendLine("         }")
                .AppendLine("    else {")
                .AppendLine("         var cb1=document.all[cb1];")
                .AppendLine("         var tb1=document.all[tb1];")
                .AppendLine("         var lnk1=document.all[lnk1];")
                .AppendLine("    }")
                .AppendLine("    if ((cb1 == null) || (tb1 == null) || (lnk1 == null)) return void(0);")
                .AppendLine("    if (cb1.checked) {")
                .AppendLine("         tb1.style.display='';")
                .AppendLine("         lnk1.style.display='';")
                .AppendLine("         }")
                .AppendLine("    else {")
                .AppendLine("         tb1.style.display='none';")
                .AppendLine("         lnk1.style.display='none';")
                .AppendLine("    }")
                .AppendLine("    }")
            End With
            If Not Page.ClientScript.IsClientScriptBlockRegistered(GetType(WESNet.DNN.Modules.EPrayer.ManageUsers), "ManageUsersJS") Then
                Page.ClientScript.RegisterClientScriptBlock(GetType(WESNet.DNN.Modules.EPrayer.ManageUsers), "ManageUsersJS", SettingsScript.ToString, True)
            End If
        End Sub

        Protected Sub gvUsers_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles gvUsers.RowCancelingEdit
            gvUsers.EditIndex = -1
            BindData()
            trDetailsView.Visible = False
            cmdReturn.Visible = True
        End Sub

        Protected Sub gvUsers_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvUsers.RowDataBound
            If e.Row.RowType = DataControlRowType.DataRow Then
                Dim ui As UserInfo = CType(e.Row.DataItem, UserInfo)

                If gvUsers.Columns(6).Visible AndAlso Null.IsNull(ui.LastVisitedDate) Then
                    CType(e.Row.Cells(6).FindControl("lblLastVisitedDate"), Label).Text = String.Empty
                End If

                If gvUsers.Columns(7).Visible AndAlso Null.IsNull(ui.LastPostedDate) Then
                    CType(e.Row.Cells(7).FindControl("lblLastPostedDate"), Label).Text = String.Empty
                    CType(e.Row.Cells(7).FindControl("lnkLastPostID"), HyperLink).Visible = False
                End If
            End If
        End Sub

        Protected Sub cmdReturn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdReturn.Click
            Try
                Response.Redirect(ReturnUrl, True)
            Catch exc As Exception
                ProcessModuleLoadException(Me, exc)
            End Try
        End Sub

        Protected Sub gvUsers_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles gvUsers.RowDeleting
            Dim UserID As Integer = CInt(gvUsers.DataKeys(e.RowIndex).Value)
            Dim epc As New EPrayerController
            epc.DeleteUser(ModuleId, UserID)
            BindData()
        End Sub

        Protected Sub gvUsers_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles gvUsers.RowEditing
            gvUsers.EditIndex = e.NewEditIndex
            BindData()
            DisplayUser(CInt(gvUsers.DataKeys(gvUsers.EditIndex).Value), False)
        End Sub

        Protected Sub gvUsers_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvUsers.RowUpdating
            Submit()
        End Sub

        Protected Sub gvUsers_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles gvUsers.SelectedIndexChanged
            Dim ProfileUrl As String
            If IsAdministrator Then
                Dim mc As New ModuleController
                Dim mi As Entities.Modules.ModuleInfo = mc.GetModuleByDefinition(PortalId, "User Accounts")
                If Not mi Is Nothing Then
                    ProfileUrl = NavigateURL(mi.TabID, "Edit", "mid=" & mi.ModuleID.ToString, "UserID=" & gvUsers.SelectedValue.ToString, "returnurl=" & Request.RawUrl)
                    Response.Redirect(ProfileUrl, True)
                End If
            Else
                Response.Redirect(AccessDeniedURL(Localize("No_Access")), True)
            End If
        End Sub

        Protected Sub ddlFilterOn_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlFilterOn.SelectedIndexChanged
            If ddlFilterOn.SelectedIndex <> -1 Then
                CurrentPage = 1 'reset to first page when filter is applied
                OrderByField = ddlFilterOn.SelectedValue
                Dim url As String = EditUrl("", "", "mngusers", GetQueryStringParams())
                Response.Redirect(url, True)
            End If
        End Sub

        Protected Sub ddlPageSize_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlPageSize.SelectedIndexChanged
            CurrentPage = 1 'reset to first page when filter is applied
            Response.Redirect(EditUrl("", "", "mngusers", GetQueryStringParams()), True)
        End Sub

        Protected Sub cmdCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdCancel.Click
            gvUsers.EditIndex = -1
            BindData()
            trDetailsView.Visible = False
            trUsers.Visible = True
            cmdReturn.Visible = True
        End Sub

        Protected Sub cmdSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdSubmit.Click
            Submit()
        End Sub

#End Region

    End Class

End Namespace